'''
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
'''

'''
 * Builtin data type to represent XMLLiteral (i.e. items created
 * by use of <code>rdf:parsetype='literal'</code>.
'''

from base.datatypes.BaseDatatype import BaseDatatype
from base.datatypes.RDFDatatype import RDFDatatype
from base.shared.DatatypeFormatException import DatatypeFormatException

# @SuppressWarnings("deprecation")
class XMLLiteralType(BaseDatatype):

    def __init__(self, uri):
        super().__init__(uri)
    

    '''
     * Convert a serialize a value of this datatype out
     * to lexical form.
    '''
    #@Override
    # param Object
    # return String
    def unparse(self, value):
        return str(value)
    

    '''
     * Parse a lexical form of this datatype to a value
     *
     * @throws DatatypeFormatException if the lexical form is not legal
    '''
    #@Override
    # param String
    # return Object
    # throws DatatypeFormatException
    def parse(self, lexicalForm):
        if not self.isValid(lexicalForm):
            raise DatatypeFormatException("Bad rdf:XMLLiteral", None, None)
        return lexicalForm
    

    '''
     * Test whether the given string is a legal lexical form
     * of this datatype.
    '''
    #@Override
    # param String
    # return boolean
    # TODO
    def isValid(self, lexicalForm):
        # return True
        '''
         * To check the lexical form we construct
         * a dummy RDF/XML document and parse it with
         * ARP. ARP performs an exclusive canonicalization,
         * the dummy document has exactly one triple.
         * If the lexicalForm is valid then the resulting
         * literal found by ARP is unchanged.
         * All other scenarios are either impossible
         * or occur because the lexical form is invalid.
        '''


        # status[0] true on error or other reason to know that this is not well-formed
        # status[1] true once first triple found
        # status[2] the result (good if status[1] and not status[0]).

        # final boolean status[] = boolean[]{false, false, false};
        '''
        status = [False, False, False]
        ARP arp = ARP()

        arp.getHandlers().setErrorHandler(ErrorHandler():
            #@Override
            # param
            # return
            void fatalError(SAXParseException e):
                 status[0] = true
            

            #@Override
            # param
            # return
            void error(SAXParseException e):
                 status[0] = true
            

            #@Override
            # param
            # return
            void warning(SAXParseException e):
                status[0] = true
            
        )
        '''

        '''
        arp.getHandlers().setStatementHandler(new StatementHandler() {
            @Override
            public void statement(AResource a, AResource b, ALiteral l) {
                # this method is invoked exactly once
                #  * while parsing the dummy document.
                #  * The l argument is in exclusive canonical XML and
                #  * corresponds to where the lexical form has been
                #  * in the dummy document. The lexical form is valid
                #  * iff it is unchanged.
                if (status[1] || !l.isWellFormedXML()) {
                    status[0] = true;
                }
                //throw new BrokenException("plain literal in XMLLiteral code.");
                status[1] = true;
                status[2] = l.toString().equals(lexicalForm);
            }

            @Override
            public void statement(AResource a, AResource b, AResource l) {
                status[0] = true;
                //throw new BrokenException("resource valued RDF/XML in XMLLiteral code.");
            }
        });
        '''
        try:

            pass
            # arp.load(new StringReader(
            #         "<rdf:RDF  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n"
            #                 + "<rdf:Description><rdf:value rdf:parseType='Literal'>"
            #                 + lexicalForm + "</rdf:value>\n"
            #                 + "</rdf:Description></rdf:RDF>"
            # ));

        except Exception as e:
            return False

        # return (not status[0]) and status[1] and status[2]
        return True


# String
XMLLiteralTypeURI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"

# Singleton instance

# Include the string for the RDF namespace, not use RDF.getURI(), to avoid an initializer circularity
# RDFDatatype
theXMLLiteralType = XMLLiteralType(XMLLiteralTypeURI)
